<?php

/**
 * 初始化管理后台菜单
 */

namespace Command\Menu;

use Exception;
use Project\Admin\Models\AdminMenu;

class Install
{
    public $bar;

    public function __invoke($obj, $bar)
    {
        if (!$this->menuExists()) {
            return "Admin 菜单已安装, 如需重复安装, 请删除 commands\menu 目录下的 install.lock 文件. \n注意: 重复安装会清空所有已有菜单!";
        }
        if (!$obj->confirm("安装将会清空已有的 Admin 菜单，是否确定安装 Admin 菜单？")) {
            return '已退出安装';
        }
        if (!file_exists(base_path('init/menu.json'))) {
            return '缺少菜单文件';
        }
        $menus = json_decode(file_get_contents(base_path('init/menu.json')), true);
        if (json_last_error() !== JSON_ERROR_NONE) {
            return '菜单数据结构错误，请检查文件完整性';
        }

        $obj->newLine(2);

        $count = 0;
        $this->countArr($menus, $count);

        $this->bar = $bar->createProgressBar($count);
        $this->bar->start();

        AdminMenu::truncate();

        $obj->newLine(2);

        try {
            if ($this->menuCreate($menus)) {
                $this->bar->finish();
                file_put_contents(base_path('commands/Menu/install.lock'), date('Y-m-d H:i:s'));

                $obj->newLine(3);

                return '菜单配置成功';
            }
        } catch (Exception $e) {
            return $e->getMessage();
        }
        return '未知错误';
    }

    protected function menuExists()
    {
        return !file_exists(base_path('commands/Menu/install.lock'));
    }

    protected function countArr($menus, &$count)
    {
        foreach ($menus as $v) {
            if (is_array($v)) {
                $count++;
                if (($v['children'] ?? false)) {
                    $this->countArr($v['children'], $count);
                }
            } else
                continue;
        }
    }

    protected function menuCreate(array $menus, int $pid = 0)
    {
        foreach ($menus as $k => $v) {
            $_tmp = array_merge([
                'parent_id'   => $pid,
                'order'       => $k,
                'cache'       => 'n',
                'hidden'      => 'n',
                'redirect'    => 'y',
                'always_show' => 'y',
                'component'   => 'layout'
            ], collect($v)->only(
                'name',
                'icon',
                'path',
                'component',
                'cache',
                'hidden',
                'redirect',
                'always_show',
                'active_menu'
            )->all());
            $_menu = AdminMenu::create($_tmp);
            $this->bar->advance();
            if (($v['children'] ?? false)) {
                $this->menuCreate($v['children'], $_menu->id);
            }
        }
        return true;
    }
}
